package com.metaverse.backend.web.app;


import com.metaverse.backend.config.RedisCacheKey;
import com.metaverse.backend.domain.PlayerData;
import com.metaverse.backend.douyin.PlayerDataDTO;
import com.metaverse.backend.douyin.RoomDataDTO;
import com.metaverse.backend.dto.PageDTO;
import com.metaverse.backend.dto.PalyerVariationDto;
import com.metaverse.backend.dto.RankDTO;
import com.metaverse.backend.dto.RoomProgressUpdateDTO;
import com.metaverse.backend.security.JwtUser;
import com.metaverse.backend.service.PlayerDataService;
import com.metaverse.backend.service.RoomDataContext;
import com.metaverse.backend.service.RoundHelper;
import com.metaverse.backend.utils.BusiResult;
import com.metaverse.backend.web.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@AllArgsConstructor
@RestController
@RequestMapping("/app/room")
@Api(tags="获取房间数据")
public class RoomController extends BaseController {


    public RoomDataContext roomDataContext;

    private RoundHelper roundHelper;



    @PostMapping("startGame")
    @ApiOperation("开始游戏")
    @ApiImplicitParams({
            @ApiImplicitParam(name="gameVersion", value="游戏版本号默认1.0"),
    })
    public BusiResult<RoomDataDTO> startGame(String gameVersion){
        JwtUser user =  currentUser();
        RoomDataDTO roomDataDTO = roomDataContext.start(user.getUser() , currentRoomId(), gameVersion );
        return BusiResult.success(roomDataDTO );
    }

    @PostMapping("reconnect")
    @ApiOperation("重连（如果返回空就不是重连）")
    public BusiResult<RoomDataDTO> reconnect(){
        JwtUser user =  currentUser();
        return BusiResult.success( roomDataContext.reconnect(user.getUser() , currentRoomId() ));
    }



    @PostMapping("endGame")
    @ApiOperation("结束一局游戏，获取排行榜")
    public BusiResult<List<PlayerDataDTO>> endGame(){
        JwtUser user =  currentUser();
        List<PlayerDataDTO>  list = roomDataContext.end(user.getUser() , currentRoomId() );
        return BusiResult.success(list);
    }


    @PostMapping("getRoomData")
    @ApiOperation("前端定时获取房间变动数据")
    public BusiResult<RoomDataDTO> getRoomData(){

        String roomId = currentRoomId();
        String roundId= roundHelper.currentRoundId(roomId);
        RoomDataDTO roomDataDTO = roomDataContext.readNewMsg(roomId, roundId);
        if(roomDataDTO.hasMsg()){
            log.info("推送房间消息:{}", roomDataDTO);
        }

        return BusiResult.success(roomDataDTO);
    }


    /**
     * 更新游戏进度
     * @return
     */
    @PostMapping("updateRoomProgress")
    @ApiOperation("更新房间游戏进度")
    @ApiImplicitParams({
    @ApiImplicitParam(
        name = "roomProgressUpdateDTOList",
        value = "房间进度更新列表",
        dataType = "List<RoomProgressUpdateDTO>",
        required = true
    )
})

    public BusiResult<RoomDataDTO> updateRoomProgress(@RequestBody List<RoomProgressUpdateDTO> roomProgressUpdateDTOList){

        JwtUser user = currentUser();
        String roomId = currentRoomId();
        //更新房间数据
        RoomDataDTO roomDataDTO  = roomDataContext.updateRoomDataProgress(roomId, roomProgressUpdateDTOList);

        return BusiResult.success(roomDataDTO);
    }

    private RedisTemplate<String, Object> redisTemplate;
    private PlayerDataService playerDataService;
    /**
     * sxzw数据展示一百条
     * @return
     */
    @PostMapping("getRank")
    @ApiOperation("排行榜")
    public BusiResult< List<RankDTO>> getRank(@RequestBody PageDTO pageDTO){
        List<RankDTO> rankList = new ArrayList<>();
        int start = pageDTO.getPage() * pageDTO.getSize();
        Set<ZSetOperations.TypedTuple<Object>> list = null;

        list = redisTemplate.opsForZSet().reverseRangeWithScores(RedisCacheKey.RANKING, start, 100);

        if (list != null) {
            for (ZSetOperations.TypedTuple<Object> t : list) {
                Long score = Objects.requireNonNull(t.getScore()).longValue();
                String openid = Objects.requireNonNull(t.getValue()).toString();
                start++;
                RankDTO rankDTO = new RankDTO();
                rankDTO.setRank(start);
                rankDTO.setScore(score);
                Double winstreak = redisTemplate.opsForZSet().score(RedisCacheKey.WINSTREAK,openid);
                rankDTO.setWinningStreak(winstreak==null?0:winstreak.intValue());
                Optional<PlayerData> playerData = playerDataService.findBySecOpenid(openid);
                if (playerData.isPresent()) {
                    rankDTO.setNickname(playerData.get().getNickname());
                    rankDTO.setAvatar_url(playerData.get().getAvatar_url());
                    rankList.add(rankDTO);
                }
            }
        }
        return BusiResult.success(rankList);
    }

    @PostMapping("getPlayerVariation")
    @ApiOperation("获取玩家变化")
    @ApiImplicitParams({
            @ApiImplicitParam(name="openid", value="用户openid"),
            @ApiImplicitParam(name="ballCount", value="球数"),
    })
    public BusiResult<String > getPlayerVariation(List<PalyerVariationDto> dataList){
        //String转JSon
        String roomId = currentRoomId();

        String roundId= roundHelper.currentRoundId(roomId);
        for (PalyerVariationDto dto : dataList) {
            roomDataContext.updatePlayerProgress(dto.getOpenid(), dto.getBallCount(), roomId, roundId);
        }
        return BusiResult.success(null);
    }


}
